import { h } from 'vue';
import { Subject, Unsubscribable } from 'rxjs';
import { FormDruipartController, IParam, IViewStateParam, MobFormEvents, Util, ViewTool } from 'ibz-core';
import { ComponentBase, GenerateComponent } from '../../component-base';

export class AppFormDruipartProps {
  /**
   * @description 表单数据
   * @type {string}
   * @memberof AppFormDruipartProps
   */
  data: string = '';

  /**
   * @description 名称
   * @type {string}
   * @memberof AppFormDruipartProps
   */
  name: string = '';

  /**
   * @description 关系界面控制器
   * @type {IParam}
   * @memberof AppFormDruipartProps
   */
  c: IParam = {};

  /**
   * @description 应用实体参数名称
   * @type {string}
   * @memberof AppFormDruipartProps
   */
  parameterName: string = '';

  /**
   * @description 表单状态
   * @type {(Subject<IViewStateParam> | null)}
   * @memberof AppFormDruipartProps
   */
  formState: Subject<IViewStateParam> | null = null;

  /**
   * @description 应用上下文
   * @type {IParam}
   * @memberof AppFormDruipartProps
   */
  navContext: IParam = {};

  /**
   * @description 视图参数
   * @type {IParam}
   * @memberof AppFormDruipartProps
   */
  navParam: IParam = {};

  /**
   * @description 视图操作参数集合
   * @type {IParam}
   * @memberof AppFormDruipartProps
   */
  viewCtx: IParam = {};

  /**
   * @description 忽略表单值变更
   * @type {boolean}
   * @memberof AppFormDruipartProps
   */
  ignorefieldvaluechange: boolean = false;

  /**
   * 模型服务
   *
   * @type {IParam}
   * @memberof AppFormDruipartProps
   */
  modelService: IParam = {};
}

//  表单关系界面
export class AppFormDruipart extends ComponentBase<AppFormDruipartProps> {
  /**
   * @description 关系视图组件
   * @type {string}
   * @memberof AppFormDruipart
   */
  public viewComponent: string = '';

  /**
   * @description 刷新节点
   * @public
   * @type {string[]}
   * @memberof AppFormDRUIPart
   */
  public hookItems: string[] = [];

  /**
   * @description 关系视图控制器
   * @type {FormDruipartController}
   * @memberof AppFormDruipart
   */
  public c!: FormDruipartController;

  /**
   * @description 关系界面向视图下发指令对象
   * @public
   * @type {Subject<IViewStateParam>}
   * @memberof AppFormDruipart
   */
  public formState: Subject<IViewStateParam> = new Subject();

  /**
   * @description 应用实体参数名称
   * @type {string}
   * @memberof AppFormDRUIPart
   */
  public parameterName: string = '';

  /**
   * @description 部件name
   * @type {string}
   * @memberof AppFormDRUIPart
   */
  public name: string = '';

  /**
   * @description 表单状态事件
   * @public
   * @type {(Unsubscribable | undefined)}
   * @memberof AppFormDRUIPart
   */
  public formStateEvent: Unsubscribable | undefined;

  /**
   * @description 表单老数据
   * @public
   * @type {(Unsubscribable | undefined)}
   * @memberof AppFormDRUIPart
   */
  public oldFormData: IParam = {};

  /**
   * @description 唯一标识
   * @type {[string]}
   * @memberof AppFormDRUIPart
   */
  public uuid: string = Util.createUUID();

  /**
   * @description 是否启用遮罩
   * @type {boolean}
   * @memberof AppFormDRUIPart
   */
  public blockUI: boolean = false;

  /**
   * @description 是否刷新关系数据
   * @public
   * @type {boolean}
   * @memberof AppFormDRUIPart
   */
  public isRelationalData: boolean = true;

  /**
   * @description 存储应用上下文
   * @public
   * @type {IParam}
   * @memberof AppFormDRUIPart
   */
  public embedViewContext: IParam = {};

  /**
   * @description 存储应用视图参数
   * @public
   * @type {IParam}
   * @memberof AppFormDRUIPart
   */
  public embedViewParam: IParam = {};

  /**
   * @description 初始化
   * @memberof AppFormDRUIPart
   */
  setup() {
    this.c = this.props.c as FormDruipartController;
  }

  /**
   * @description 挂载
   * @memberof AppFormDRUIPart
   */
  init() {
    this.c.initInputData(this.props);
    this.initFormDrUIPart();
    this.initViewComponent();
  }

  /**
   * @description 初始化关系界面
   * @memberof AppFormDRUIPart
   */
  public initFormDrUIPart() {
    if (this.c.refreshitems) {
      this.hookItems = [...this.c.refreshitems.split(';')];
    }
    this.parameterName = this.props.parameterName;
    this.name = this.props.name;
    this.embedViewContext = this.props.navContext;
    this.embedViewParam = {};
    const formDRState = this.props.formState;
    const embedViewName = this.c.embeddedView?.codeName;
    if (!Object.is(this.c.paramItem, this.parameterName.toLowerCase())) {
      this.hookItems.push(this.c.paramItem);
    }
    if (formDRState) {
      this.formStateEvent = formDRState.subscribe(({ tag, action, data }: IViewStateParam) => {
        if (!Object.is(this.name, tag)) {
          return;
        }
        // 表单加载完成
        if (Object.is(action, MobFormEvents.LOAD_SUCCESS) || Object.is(action, MobFormEvents.LOAD_DRAFT_SUCCESS)) {
          this.refreshDRUIPart(data);
        }
        // 表单保存之前
        if (Object.is(action, MobFormEvents.BEFORE_SAVE)) {
          if (this.c.tempMode && this.c.tempMode == 2) {
            this.formState.next({ tag: embedViewName, action: 'save', data: data });
          } else {
            if (data && !Object.is(data.srfuf, '0')) {
              (this.formState as Subject<IViewStateParam>).next({ tag: embedViewName, action: 'save', data: data });
            } else {
              this.c.embedViewDataSaved();
            }
          }
        }
        // 表单保存完成
        if (Object.is(action, MobFormEvents.SAVE_SUCCESS)) {
          this.refreshDRUIPart(data);
        }
        // 表单项更新
        if (Object.is(action, 'updateFormItem')) {
          if (!data) return;
          let refreshRefview = false;
          Object.keys(data).some((name: string) => {
            const index = this.hookItems.findIndex((_name: string) => Object.is(_name, name));
            refreshRefview = index !== -1 ? true : false;
            return refreshRefview;
          });
          if (refreshRefview) {
            this.refreshDRUIPart(data);
          }
        }
      });
    }
  }

  /**
   * @description 监听数据变化
   * @memberof AppFormDRUIPart
   */
  watchEffect() {
    this.c.initInputData(this.props);
    if (this.hookItems.length > 0) {
      let refreshRefview = false;
      this.hookItems.forEach((item: string) => {
        if (!Object.is(this.oldFormData[item], this.c.data[item])) {
          refreshRefview = true;
        }
      });
      this.oldFormData = Util.deepCopy(this.c.data);
      if (refreshRefview) {
        this.refreshDRUIPart(this.c.data);
      }
    }
  }

  /**
   * @description 初始化视图组件名称
   * @memberof AppFormDRUIPart
   */
  public initViewComponent() {
    this.viewComponent = App.getComponentService().getViewTypeComponent(
      this.c.embeddedView?.viewType,
      this.c.embeddedView?.viewStyle,
      this.c.embeddedView?.getPSSysPFPlugin()?.pluginCode,
    );
  }

  /**
   * @description 刷新关系页面
   * @public
   * @returns {void}
   * @memberof AppFormDRUIPart
   */
  public refreshDRUIPart(formData: IParam | undefined): void {
    if (Object.is(this.c.parentdata?.SRFPARENTTYPE, 'CUSTOM')) {
      this.isRelationalData = false;
    }
    const _paramitem = (formData as IParam)[this.c.paramItem];
    const tempContext: IParam = {};
    const tempParam: IParam = {};
    const _parameters: any[] = [...ViewTool.getIndexParameters(), ...this.c.parameters];
    _parameters.forEach((parameter: any) => {
      const { pathName, parameterName }: { pathName: string; parameterName: string } = parameter;
      if ((formData as IParam)[parameterName] && !Object.is((formData as IParam)[parameterName], '')) {
        Object.assign(tempContext, {
          [parameterName]: (formData as IParam)[parameterName],
        });
      }
    });
    Object.assign(tempContext, { [this.c.paramItem]: _paramitem });
    // //设置顶层视图唯一标识
    Object.assign(tempContext, this.c.context);
    Object.assign(tempContext, {
      srfparentdename: this.parameterName,
      srfparentkey: _paramitem,
    });
    Object.assign(tempParam, {
      srfparentdename: this.parameterName,
      srfparentkey: _paramitem,
    });
    // 设置局部上下文
    if (this.c.localContext && Object.keys(this.c.localContext).length > 0) {
      const _context: any = Util.computedNavData(formData, tempContext, this.c.viewParam, this.c.localContext);
      Object.assign(tempContext, _context);
    }
    this.embedViewContext = tempContext;
    // // 设置局部参数
    if (this.c.localParam && Object.keys(this.c.localParam).length > 0) {
      const _param: any = Util.computedNavData(formData, tempContext, this.c.viewParam, this.c.localParam);
      Object.assign(tempParam, _param);
    }
    if (this.c.viewParam?.hasOwnProperty('copymode')) {
      Object.assign(tempParam, { copymode: this.props.c.copymode });
    }
    this.embedViewParam = tempParam;
    if (this.isRelationalData) {
      if (this.c.tempMode && Object.is(this.c.tempMode, 2)) {
        this.blockUIStop();
      } else {
        if (!_paramitem || _paramitem == null || Object.is(_paramitem, '')) {
          this.blockUIStart();
          return;
        } else {
          this.blockUIStop();
        }
      }
    }
    //根据key值刷新
    this.uuid = Util.createUUID();
    // 重置状态对象
    this.formState = new Subject();
    this.forceUpdate();
  }

  /**
   * @description 开启遮罩
   * @public
   * @memberof AppFormDRUIPart
   */
  public blockUIStart(): void {
    this.blockUI = true;
  }

  /**
   * @description 关闭遮罩
   * @public
   * @memberof AppFormDRUIPart
   */
  public blockUIStop(): void {
    this.blockUI = false;
  }

  /**
   * @description 处理视图事件
   * @public
   * @memberof AppFormDRUIPart
   */
  public handleViewEvent(viewname: string, action: string, data: any) {
    switch (action) {
      case 'save':
        this.c.embedViewDataSaved();
        break;
    }
  }

  /**
   * @description 组件销毁
   * @public
   * @memberof AppFormDRUIPart
   */
  unmounted(): void {
    if (this.formStateEvent) {
      this.formStateEvent.unsubscribe();
    }
  }

  /**
   * @description 绘制关系视图
   * @public
   * @memberof AppFormDRUIPart
   */
  public renderDruipartView() {
    return h(this.viewComponent, {
      key: this.uuid,
      class: `form-druipart-view ${this.c?.customClass ? this.c?.customClass : ''}`,
      style: this.c.customStyle,
      viewPath: this.c.embeddedView?.modelPath,
      navContext: this.embedViewContext,
      navParam: this.embedViewParam,
      navDatas: [this.c.data],
      viewShowMode: 'EMBEDDED',
      viewState: this.formState,
      onViewEvent: ({ viewname, action, data }: { viewname: string; action: string; data: any }) => {
        this.handleViewEvent(viewname, action, data);
      },
    });
  }

  /**
   * @description 绘制内容
   * @memberof AppFromItem
   */
  render() {
    return (
      <div class='form-druipart'>
        {this.blockUI && (
          <div class='form-druipart-spin'>
            <span>{this.$tl('widget.mobformdruipart.tooltip', '请先保存主数据')}</span>
          </div>
        )}
        {this.renderDruipartView()}
      </div>
    );
  }
}

//  表单关系界面组件
export const AppFormDruipartComponent = GenerateComponent(AppFormDruipart, Object.keys(new AppFormDruipartProps()));
